package com.jt;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.concurrent.locks.Lock;

/**
 * 构建一个数据源对象JedisDataSource，在此类中构建一个方法
 * getConnection()，能通过此方法对外提供一个连接，这个连接
 * 每次都是从JedisPool获取，但是不能每次
 * 获取连接都创建一个JedisPool对象，请问
 * 你如何设计？
 */
public class JedisDataSource {//JedisDataSource.class
    private static final String HOST="192.168.192.128";
    private static final int PORT=6379;
    /**
     * volatile 可以修饰属性
     * 1)可以禁止指令重排序(JVM为了优化指令的执行有可能会对指令进行排序)
     * 2)可以保证其可见性(一个线程修改了值，其它线程可见)
     * 3)不能保证其原子性(要么都执行，要么都不执行)
     */
    private static volatile JedisPool jedisPool;
    //方案1:饿汉式设计(类加载时创建对象)
//    static{
//         JedisPoolConfig poolConfig=new JedisPoolConfig();
//         poolConfig.setMaxTotal(1000);
//         poolConfig.setMaxIdle(60);
//         jedisPool=new JedisPool(poolConfig,HOST,PORT);
//    }
//    public static Jedis getConnection(){
//        return jedisPool.getResource();//从池获取一个连接
//    }

    //方案2:懒汉式设计(何时应用何时创建池对象)
    public  static Jedis getConnection(){//JedisDataSource.class
        if(jedisPool==null) {
            synchronized (JedisDataSource.class) {
               if (jedisPool == null) {
                    JedisPoolConfig poolConfig = new JedisPoolConfig();
                    poolConfig.setMaxTotal(1000);
                    poolConfig.setMaxIdle(60);
                    jedisPool = new JedisPool(poolConfig,HOST, PORT);
                    //1.分配内存
                    //2.初始化属性
                    //3.执行构造方法
                    //4.将对象赋值给引用变量
                }
            }
        }
        return jedisPool.getResource();
    }
    public static void close(){
        jedisPool.close();
    }
}
